/*
 * Copyright (c) 2018-2023 北京华恒盛世科技有限公司
 * QUICKPOOL is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/resource.h>

#include "common.h"

void
daemonize_myself(void)
{
    int i;
    struct rlimit rlp;
    char errMsg[PATH_MAX+1];

    switch (fork()) {
    case 0:
        break;
    case -1:
        snprintf(errMsg, PATH_MAX, "%s: fork() failed :%s", __func__, strerror(errno));
        perror(errMsg);
        exit(-1);
    default:
        exit(0);
    }

    setsid();

#ifdef RLIMIT_NOFILE
    getrlimit (RLIMIT_NOFILE, &rlp);
    rlp.rlim_cur = rlp.rlim_max;
    setrlimit (RLIMIT_NOFILE, &rlp);
#endif

#ifdef RLIMIT_CORE
    getrlimit (RLIMIT_CORE, &rlp);
    rlp.rlim_cur = rlp.rlim_max;
    setrlimit (RLIMIT_CORE, &rlp);
#endif

    for (i = 0; i < 3; i++)
	close(i);

    i = open("/dev/null", O_RDWR);
    if (i != 0) {
	dup2(i, 0);
	close(i);
    }
    dup2(0, 1);
    dup2(0, 2);

    return;
}

static char daemon_dir[PATH_MAX+1];
void
save_daemon_path(char *argv0)
{
    int i;

    daemon_dir[0]='\0';
    if (argv0[0] != '/') {
        if (getcwd(daemon_dir, sizeof(daemon_dir))) {
            strncat(daemon_dir, "/", PATH_MAX);
        }
    }

    strncat(daemon_dir, argv0, PATH_MAX);
    for (i = strlen(daemon_dir); i >= 0 && daemon_dir[i] != '/'; i--)
        ;

    daemon_dir[i] = '\0';

    return;
}

char *
get_daemon_path(const char *name, char *serverdir, char *path)
{
    strncpy(path, daemon_dir, PATH_MAX);
    strncat(path, name, PATH_MAX);

    if (0 > access(path, X_OK)) {

        if (0 == strcmp(daemon_dir, serverdir)) {
            log_message(ERR, NOCLASS, "%s: cannot access <%s> at %s due to %m.",
                        __func__, name, daemon_dir);
            return NULL;
        }

        strncpy(path, serverdir, PATH_MAX);
        strncat(path, name, PATH_MAX);

        if (0 > access(path, X_OK)) {
            log_message(ERR, NOCLASS, "%s: cannot access <%s> at both %s and %s: %m.",
                        __func__, name, daemon_dir, serverdir);
            return NULL;
        }
    }

    return path;
}


